﻿//-----------------------------------------------------------------------
// <copyright file="PaintView.cs" company="Codingworks Game Development">
//     Copyright (c) codingworks. All rights reserved.
// </copyright>
// <author> codingworks </author>
// <email> coding2233@163.com </email>
// <time> 2017-12-10 </time>
//-----------------------------------------------------------------------

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


public class PaintView : MonoBehaviour
{
    #region 属性

    //绘图shader&material
    [SerializeField]
    private Shader _paintBrushShader;
    [SerializeField]
    private Material _paintBrushMat;

    //清理renderTexture的shader&material
    [SerializeField]
    private Shader _clearBrushShader;
    [SerializeField]
    private Material _clearBrushMat;


    //绘画的画布
    [SerializeField]
    private RawImage _drawImage;
    private RectTransform _deawAreaRect;
    private RenderTexture _renderTex;  //renderTexture

    #region 笔刷


    [SerializeField]
    private RawImage _defaultBrushRawImage;  //默认笔刷 
    [SerializeField]
    private Texture _defaultBrushTex;    //默认笔刷&笔刷合集


    [SerializeField]
    private Image _defaultColorImage;  //默认笔刷颜色 
    [SerializeField]
    private Color _defaultColor;    //笔刷的默认颜色&颜色合集



    [SerializeField]
    private Text _brushSizeText; //笔刷大小的slider 
    [SerializeField]
    private float _brushSize = 300;    //笔刷的大小
    [SerializeField]
    private float _brushLerpSize; //笔刷的间隔大小

    #endregion

    private int _screenWidth;//屏幕的宽高
    private int _screenHeight;

    private Vector2 _lastPoint;  //默认上一次点的位置
    #endregion

    void Start()
    {
        InitData();
    }

    private void Update()
    {

        DragUpdate();
        DragEnd();

        if (Input.GetKeyDown(KeyCode.Space))
            SetBrushColor(new Color(0, 0, 0, 0));
    }


    #region 外部接口

    /// <summary>
    /// 拖拽
    /// </summary>
    public void DragUpdate()
    {
        if (_renderTex && _paintBrushMat)
        {
            if (Input.GetMouseButton(0))
                LerpPaint(Input.mousePosition);
        }
    }
    /// <summary>
    /// 拖拽结束
    /// </summary>
    public void DragEnd()
    {
        if (Input.GetMouseButtonUp(0))
            _lastPoint = Vector2.zero;
    }


    /// <summary>
    /// 选择颜色
    /// </summary>
    /// <param name="image"></param>
    public void SelectColor(Image image)
    {
        SetBrushColor(image.color);
    }

    /// <summary>
    /// 选择笔刷
    /// </summary>
    /// <param name="rawImage"></param>
    public void SelectBrush(RawImage rawImage)
    {
        SetBrushTexture(rawImage.texture);
    }
    /// <summary>
    /// 设置笔刷大小
    /// </summary>
    /// <param name="value"></param>
    public void BrushSizeChanged(Slider slider)
    {
        //  float value = slider.maxValue + slider.minValue - slider.value;
        SetBrushSize(Remap(slider.value, 300.0f, 30.0f));
        if (_brushSizeText == null)
            _brushSizeText = slider.transform.Find("Background/Text").GetComponent<Text>();
        if (_brushSizeText)
            _brushSizeText.text = slider.value.ToString("f2");
    }

    public void SaveRenderImage()
    {
        PhotoHelp.SaveRenderTextureToPNG(_renderTex, "temp", "test");
    }

    public void LoadRenderImage()
    {
        StartCoroutine(PhotoHelp.LoadRenderTexture("temp", "test", (tex) =>
        {
            if (_deawAreaRect.Find("Image"))
                _deawAreaRect.Find("Image").GetComponent<Image>().sprite = tex;
        }));
    }


    private void SetBrushSize(float size)
    {
        _brushSize = size;
        _paintBrushMat.SetFloat("_Size", _brushSize);


        float _brushSize2 = _brushSize;
        if (_brushSize <= 1)
            _brushSize2 = 1;

        if (_defaultBrushTex)
            _brushLerpSize = (_defaultBrushTex.width + _defaultBrushTex.height) / 2.0f / _brushSize2; 
    }

    private void SetBrushTexture(Texture texture)
    {
        _defaultBrushTex = texture;
        _paintBrushMat.SetTexture("_BrushTex", _defaultBrushTex);

        if (_defaultBrushRawImage)
            _defaultBrushRawImage.texture = _defaultBrushTex;
    }

    private void SetBrushColor(Color color)
    {
        _defaultColor = color;
        _paintBrushMat.SetColor("_Color", _defaultColor);

        if (_defaultColorImage)
            _defaultColorImage.color = _defaultColor;
    }

    private float Remap(float value, float startValue, float enValue) // 重映射  默认  value 为1-100
    {
        float returnValue = (value - 1.0f) / (100.0f - 1.0f);
        returnValue = (enValue - startValue) * returnValue + startValue;
        return returnValue;
    }

    #endregion

    #region 内部函数

    //初始化数据
    void InitData()
    {   
        _screenWidth = Screen.width;
        _screenHeight = Screen.height;

        if (_deawAreaRect == null)
            _deawAreaRect = _drawImage.transform.parent.GetComponent<RectTransform>();


        UpdateBrushMaterial();

        ResetRenderTex();
    }


    //更新笔刷材质
    private void UpdateBrushMaterial()
    {
        if (_paintBrushMat == null)
        {
            _paintBrushMat = new Material(_paintBrushShader);
            //_paintBrushMat.SetTexture("_BrushTex", _defaultBrushTex);
            //_paintBrushMat.SetColor("_Color", _defaultColor);
            //_paintBrushMat.SetFloat("_Size", _brushSize); 
        }

        SetBrushSize(_brushSize);

        SetBrushTexture(_defaultBrushTex);

        SetBrushColor(_defaultColor);
    }

    public void ResetRenderTex()
    {
        //if (_renderTex != null)
        //{
        //    RenderTexture.ReleaseTemporary(_renderTex);
        //}



        //_renderTex = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
        _renderTex = RenderTexture.GetTemporary((int)_deawAreaRect.rect.width, (int)_deawAreaRect.rect.height, 24);
        _drawImage.texture = _renderTex;

        if (_clearBrushMat == null)
            _clearBrushMat = new Material(_clearBrushShader);

        Graphics.Blit(null, _renderTex, _clearBrushMat);
    }





    private void LerpPaint(Vector2 point)  //插点
    {
        Paint(point);

        if (_lastPoint == Vector2.zero)
        {
            _lastPoint = point;
            return;
        }

        float dis = Vector2.Distance(point, _lastPoint);
        if (dis > _brushLerpSize)
        {
            Vector2 dir = (point - _lastPoint).normalized;
            int num = (int)(dis / _brushLerpSize);
            for (int i = 0; i < num; i++)
            {
                Vector2 newPoint = _lastPoint + dir * (i + 1) * _brushLerpSize;
                Paint(newPoint);
            }
        }
        _lastPoint = point;
    }

    private void Paint(Vector2 point) //画点
    {
        if (point.x < 0 || point.x > _screenWidth || point.y < 0 || point.y > _screenHeight)
            return;

        //Vector2 uv = new Vector2(point.x / (float)_screenWidth, point.y / (float)_screenHeight);

        Vector2 localPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(_deawAreaRect, point, null, out localPoint);

        localPoint.x += _deawAreaRect.rect.width / 2;
        localPoint.y += _deawAreaRect.rect.height / 2;


        if (localPoint.x < 0 || localPoint.x > _deawAreaRect.rect.width || localPoint.y < 0 || localPoint.y > _deawAreaRect.rect.height)
            return;

        Vector2 uv = new Vector2(localPoint.x / (float)_deawAreaRect.rect.width, localPoint.y / (float)_deawAreaRect.rect.height);


        // 0,0  1,1
        _paintBrushMat.SetVector("_UV", uv);
        Graphics.Blit(_renderTex, _renderTex, _paintBrushMat);
    }

    #endregion

}
